import json
import sys
import time
from pathlib import Path
import logging

import DataGrouping
import WordAO
import WordAR
from AORemote import AORemote


class Tee:
    """将输出同时写入文件和原始标准输出"""
    def __init__(self, file, original_stream):
        self.file = file
        self.original_stream = original_stream
        self._closed = False  # 添加关闭状态标记

    def write(self, text):
        # 写入原始标准输出（控制台）
        if self.original_stream is not None:
            try:
                self.original_stream.write(text)
                self.original_stream.flush()
            except (ValueError, OSError):
                pass  # 忽略已关闭的流错误
        # 写入文件
        if self.file is not None and not self._closed:
            try:
                self.file.write(text)
                self.file.flush()  # 立即刷新，确保内容写入文件
            except (ValueError, OSError):
                self._closed = True  # 标记为已关闭

    def flush(self):
        if self.original_stream is not None:
            try:
                self.original_stream.flush()
            except (ValueError, OSError):
                pass  # 忽略已关闭的流错误
        if self.file is not None and not self._closed:
            try:
                self.file.flush()
            except (ValueError, OSError):
                self._closed = True  # 标记为已关闭

    def close(self):
        if self.file is not None and not self._closed:
            try:
                self.file.close()
                self._closed = True
            except (ValueError, OSError):
                self._closed = True  # 即使关闭失败也标记为已关闭

    def is_closed(self):
        """检查文件是否已关闭"""
        return self._closed

    def __getattr__(self, name):
        # 将其他属性委托给原始流
        return getattr(self.original_stream, name)


def clean_old_logs(log_dir: Path, keep_last_n: int = 10, max_age_days: int = 7):
    files = sorted(
        [f for f in log_dir.glob("wordh_*.txt") if f.is_file()],  # 修改：匹配实际的文件名模式
        key=lambda f: f.stat().st_mtime,  # 按最后修改时间排序
        reverse=True
    )

    # 清除旧日志（保留最近N个）
    for f in files[keep_last_n:]:
        f.unlink()

    # 或：清除超过一定时间的日志
    now = time.time()
    for f in files:
        if now - f.stat().st_mtime > max_age_days * 86400:
            f.unlink()


def openAOJson(filePath: str) -> {}:
    with open(filePath, "r", encoding="utf-8") as file:
        data = json.load(file)  # 直接解析为 Python 对象

    return data


if __name__ == "__main__":
    # 先设置路径，以便后续日志配置能找到正确的目录
    if len(sys.argv) >= 2:
        pathT = sys.argv[1]
    else:
        pathT = 'D:\\workspace\\xizi\\AO'

    # 启用日志记录
    import datetime

    log_dir = Path(pathT) / "logs"
    log_dir.mkdir(exist_ok=True)

    # 设置日志文件 - 使用日期而不是精确到秒
    date_str = datetime.datetime.now().strftime('%Y%m%d')
    log_file = log_dir / f"wordh_{date_str}.txt"

    # 保存原始输出流
    original_stdout = sys.stdout
    original_stderr = sys.stderr

    # 打开日志文件用于写入
    log_file_handle = open(log_file, 'a', encoding='utf-8')

    # 创建 Tee 对象，同时输出到控制台和文件
    sys.stdout = Tee(log_file_handle, original_stdout)
    sys.stderr = Tee(log_file_handle, original_stderr)

    # 现在 print() 的输出会同时写入文件和控制台
    print("脚本名称:", sys.argv[0])  # 第一个参数是脚本本身
    print("参数列表:", sys.argv[1:])  # 后续参数是用户输入的

    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(levelname)s - %(message)s',
        handlers=[
            logging.FileHandler(log_file, encoding='utf-8', mode='a'),
            logging.StreamHandler(sys.stdout)
        ]
    )

    try:

        # load_ini
        jsonPath = pathT + "\\output.json"
        remoteConfigPath = pathT + "\\connectionConfig.json"

        aoJson: {} = openAOJson(jsonPath)
        remote = AORemote(remoteConfigPath)

        groupedData: DataGrouping.GroupData = DataGrouping.load_ini(aoJson, remote)
        if not isinstance(groupedData, DataGrouping.GroupData):
            raise Exception("未获取GroupData对象")

        ao_file_path: Path = WordAO.process_word_template_ao(pathT, groupedData)
        ar_file_path: Path = WordAR.process_word_template_ar(pathT, groupedData)

        remote.uploadDocuments(ao_file_path, aoJson)
        remote.uploadDocuments(ar_file_path, aoJson)

        clean_old_logs(log_dir, keep_last_n=10, max_age_days=7)
    finally:
        # 关闭日志句柄，避免文件占用
        logging.shutdown()

        # 刷新并关闭文件
        # 注意：stdout 和 stderr 共享同一个文件句柄，只需关闭一次
        if isinstance(sys.stdout, Tee):
            try:
                sys.stdout.flush()
            except (ValueError, OSError):
                pass  # 文件可能已经关闭
        if isinstance(sys.stderr, Tee):
            try:
                sys.stderr.flush()
            except (ValueError, OSError):
                pass  # 文件可能已经关闭

        # 只关闭一次文件（因为它们共享同一个文件句柄）
        if isinstance(sys.stdout, Tee) and not sys.stdout.is_closed():
            try:
                sys.stdout.close()
            except (ValueError, OSError):
                pass
        elif isinstance(sys.stderr, Tee) and not sys.stderr.is_closed():
            try:
                sys.stderr.close()
            except (ValueError, OSError):
                pass

        # 恢复原始输出
        if original_stdout is not None:
            sys.stdout = original_stdout
        if original_stderr is not None:
            sys.stderr = original_stderr
